--[[ 编码: WMS-08-10 作者:HAN 日期:2025-1-29 入口函数: EQActionProcess 功能说明: 变更记录: --]] wms_op = require( "wms_operation" ) wms_dev = require( "wms_devcomm" ) wms_task = require( "wms_task" ) wms_wh = require( "wms_wh" ) function EQActionProcess ( strLuaDEID ) local nRet, strRetInfo -- step1 获取设备动作队列 MQ_EQAction local mq_eq_action nRet, mq_eq_action = m3.GetSysCurEditDataObj( strLuaDEID, "MQ_EQAction ") if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), mq_eq_action ) end -- step2 AGV传上来的数据保存在 mq_eq_action.data 是下面这样一段Json字符串 -- {"State":"%d","No":"%s","Ext1":"%s","Ext2":"%s","Ext3":"%s","ForkliftNo":"%d","ErrCode":"%d","ExtData":"%d"} local agv_action, success success, agv_action = pcall( json.decode, mq_eq_action.data) if ( success == false ) then lua.Error( strLuaDEID, debug.getinfo(1), "动作队列中的字符串是不合法的JSON格式! "..mq_eq_action.data ) end -- 注意 动作码 是数值类型 local nActionCode = lua.StrToNumber( agv_action.State ) local strTaskCode = agv_action.No local strForkliftNo = agv_action.ForkliftNo -- step3. 获取任务信息,如果有任务编码检查一下任务是否存在 -- 检查任务的状态是否=完成,已经完成的任务也不能继续接收 action local task = {} if ( strTaskCode ~= '') then nRet, task = wms_task.GetInfo( strLuaDEID, strTaskCode ) -- 如果任务不存在或出错, 返回 if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), task ) end else task = nil end if ( task == nil ) then lua.Error( strLuaDEID, debug.getinfo(1), "设备动作队列中任务编码为空或任务编码无效! " ) end -- V3.1 if ( task.bs_state == wms_base.Get_nConst(strLuaDEID, "任务状态-完成") ) then lua.Error( strLuaDEID, debug.getinfo(1), "任务编码 = '"..task.code.."' 的任务已经完成,无法继续接受任务活动!") end if ( strForkliftNo == nil or strForkliftNo == '') then lua.Error( strLuaDEID, debug.getinfo(1), "HostToAGV 回调接口数据不完整,少车辆号(ForkliftNo)! ".. mq_eq_action.data ) end -- step4 根据设备的动作类型进行处理 local strActionValue = '' -- 附加值 -- 以下这些动作要判断一下任务里是否已经有,有返回 if ( nActionCode == wms_base.Get_nConst( strLuaDEID, "AGV-开始运行" ) or nActionCode == wms_base.Get_nConst( strLuaDEID, "AGV-搬运完成" ) or nActionCode == wms_base.Get_nConst( strLuaDEID, "AGV-取货请求" ) ) then nRet, strRetInfo = wms_task.Action_Exist( strLuaDEID, task.code, nActionCode ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "任务动作检查时出错! "..strRetInfo ) end if ( strRetInfo == "yes" ) then return end end -- 1 if ( nActionCode == wms_base.Get_nConst( strLuaDEID, "AGV-开始运行" ) ) then -- 车辆开始执行 -- 需要给任务赋值车辆代码,开始时间 if ( task.eq_code ~= "" ) then -- 如果任务已经绑定了车辆,报错 lua.Error( strLuaDEID, debug.getinfo(1), "任务编码='"..task.code.."'的任务已经绑定了设备,设备编码='"..task.eq_code.."'" ) end task.eq_code = agv_action.ForkliftNo task.bs_state = wms_base.Get_nConst(strLuaDEID, "任务状态-执行") task.start_time = os.date("%Y-%m-%d %H:%M:%S") nRet, strRetInfo = wms_task.Update( strLuaDEID, task ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "更新任务信息失败!"..strRetInfo ) end -- 2 elseif ( nActionCode == wms_base.Get_nConst( strLuaDEID, "AGV-搬运完成" ) ) then -- AGV 搬运完成 nRet, strRetInfo = wms.wms_TaskFinish( strLuaDEID, task.code ) if ( nRet ~= 0 ) then -- V7.2 local setAttr, strErr setAttr = "S_ERR = '".."在设备动作监听脚本 WMS-107-02 中执行 wms_TaskFinish 失败! 原因:"..strRetInfo.."'" nRet, strErr = mobox.addProcSQL2( "Task", task.id, setAttr ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "addProcSQL2 失败!"..strErr ) end lua.Error( strLuaDEID, debug.getinfo(1), "任务编码='"..task.code.."'的任务设置完成失败!"..strRetInfo ) end -- 4 elseif ( nActionCode == wms_base.Get_nConst( strLuaDEID, "AGV-取货完成" ) ) then -- AGV取货完成,给PLC一个完成信号 -- step1 获取线体编号 line_seg_code local line_seg_code -- 如果是入库搬运需要和输送线进行交互,如果出库不需要直接从货架取 if ( task.type == wms_base.Get_nConst( strLuaDEID, "任务类型-AGV入库搬运")) then nRet, line_seg_code = XX_GetLineSegCodeByLocCode( strLuaDEID, task.start_loc_code ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "任务编码 = '"..strTaskCode.."' 的任务属性早中起始货位不完整! "..line_seg_code ) end --PLC写入的完成信号 local body = {} body.device_code = "S7_Line_01" body.comm_code = line_seg_code.."_FINISH" body.value = {} body.value[1] = wms_base.Get_nConst( strLuaDEID, "PLC信号-AGV出框完成" ) wms_dev.WriteS7PLCCommsData( strLuaDEID, body ) end -- 货位和托盘解绑 nRet, strRetInfo = wms_wh.Loc_Container_Unbinding( strLuaDEID, task.start_loc_code, task.cntr_code, "绑定解绑方法-系统", task.code.."取货完成" ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), '货位容器解绑失败!'..strRetInfo ) end -- 6 elseif ( nActionCode == wms_base.Get_nConst( strLuaDEID, "AGV-卸货完成" ) ) then -- AGV卸货完成 -- 需要判断一下 当前 task 的任务类型 if ( task.type == wms_base.Get_nConst( strLuaDEID, "任务类型-AGV入库搬运")) then -- 货位和托盘进行绑定 -- 从任务中获取 目标位置,目标位置和托盘进行绑定 -- 从作业对象中获取容器编码(目前只是单个容器) local operation = {} nRet, operation = wms_op.GetInfo( strLuaDEID, task.op_code ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "获取编码='"..task.op_code.."'的作业对象失败! "..operation ) end -- 货位和托盘进行绑定 nRet, strRetInfo = wms_wh.Loc_Container_Binding( strLuaDEID, task.end_loc_code, operation.cntr_code, "绑定解绑方法-系统", task.code.."卸货完成" ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), '货位容器绑定失败!'..strRetInfo ) end elseif ( task.type == wms_base.Get_nConst( strLuaDEID, "任务类型-AGV出库搬运")) then -- AGV 已经把出库货品搬运到 线体出口 -- 需要给PLC发一个进框完成信号 local line_seg_code nRet, line_seg_code = XX_GetLineSegCodeByLocCode( strLuaDEID, task.end_loc_code ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "任务编码 = '"..strTaskCode.."' 的任务属性早中起始货位不完整! "..line_seg_code ) end -- 组织给PLC写入的完成信号 local body = {} body.device_code = "S7_Line_01" body.comm_code = line_seg_code.."_FINISH" body.value = {} body.value[1] = wms_base.Get_nConst( strLuaDEID, "PLC信号-AGV进框完成" ) lua.Debug( strLuaDEID, debug.getinfo(1), "AGV进框完成 body", lua.table2str(body)) wms_dev.WriteS7PLCCommsData( strLuaDEID, body ) else lua.Error( strLuaDEID, debug.getinfo(1), "任务编码 = '"..strTaskCode.."' 的任务类型不正确! " ) end -- 1101 elseif ( nActionCode == wms_base.Get_nConst( strLuaDEID, "AGV-取货请求" ) ) then -- AGV取货请求 -- 根据【任务】类型来判断 线体出入口 位置 -- 如果是入库作业,任务的开始位置是线体端,如果是出库任务的目标位置是线体端 if ( task.type == wms_base.Get_nConst( strLuaDEID, "任务类型-AGV入库搬运")) then line_loc_code = task.start_loc_code else lua.Error( strLuaDEID, debug.getinfo(1), "任务编码 = '"..strTaskCode.."' 的任务类型不正确! " ) end nRet, line_seg_code = XX_GetLineSegCodeByLocCode( strLuaDEID, line_loc_code ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "任务编码 = '"..strTaskCode.."' 的任务属性早中起始货位不完整! "..line_seg_code ) end -- 获取 线体信号,如果是有框,发出出框请求并且 AGV 的搬运任务状态设置为 "等待出框" local state = wms_dev.ReadS7PLCCommsData( strLuaDEID, "S7_Line_01", line_seg_code..'_STUS' ) -- 判断线体 (1) 是否空闲 = 0(2)是否有框 = 1 -- 有框 (3)是否允许出框 = 1 -- 允许出框 if ( state[wms_base.Get_nConst(strLuaDEID,"输送线-线体状态")] == 0 and state[wms_base.Get_nConst(strLuaDEID,"输送线-光电信号")] == 1 and state[wms_base.Get_nConst(strLuaDEID,"输送线-线体信号")] == 1 ) then -- 通知 AGV 开始取货 local strXml -- ParamNo='9 继续取货 strXml = "" nRet, strRetInfo = wms.wms_ChangeNdcOrderParameter( task.factory, task.schedule_type, strXml ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "HostToAGV推送指令失败!"..strRetInfo) end else return end -- 1102 elseif ( nActionCode == wms_base.Get_nConst( strLuaDEID, "AGV-卸货请求" ) ) then -- AGV卸货请求 -- 如果是出库作业,任务的终止位置是线体端 if ( task.type == wms_base.Get_nConst( strLuaDEID, "任务类型-AGV出库搬运")) then line_loc_code = task.end_loc_code else lua.Error( strLuaDEID, debug.getinfo(1), "任务编码 = '"..strTaskCode.."' 的任务类型不正确! " ) end nRet, line_seg_code = XX_GetLineSegCodeByLocCode( strLuaDEID, line_loc_code ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "任务编码 = '"..strTaskCode.."' 的任务属性早中终点货位不完整! "..line_seg_code ) end -- 获取 线体信号,如果是有框,发出进框请求并且 AGV 的搬运任务状态设置为 "等待出框" local state = wms_dev.ReadS7PLCCommsData( strLuaDEID, "S7_Line_01", line_seg_code..'_STUS' ) -- 判断线体 (1) 是否空闲 = 0(2)是否有框 = 0 -- 无框 (3)是否允许进框 = 2 -- 允许进框 if ( state[wms_base.Get_nConst(strLuaDEID,"输送线-线体状态")] == 0 and state[wms_base.Get_nConst(strLuaDEID,"输送线-光电信号")] == 0 and state[wms_base.Get_nConst(strLuaDEID,"输送线-线体信号")] == 2 ) then -- 通知 AGV 开始卸货 local strXml -- ParamNo='9 继续卸货 strXml = "" lua.Debug( strLuaDEID, debug.getinfo(1), "ChangeNdcOrderParameter", strXml ) --[[ nRet, strRetInfo = wms.wms_ChangeNdcOrderParameter( task.factory, task.schedule_type, strXml ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "HostToAGV推送指令失败!"..strRetInfo) end --]] else -- 如果线体的信号不能满足就返回,等下一次信号 return end end -- 根据动作码获取动作名称 local task_action = m3.AllocObject(strLuaDEID,"Task_Action") task_action.task_code = strTaskCode task_action.action_code = nActionCode task_action.eq_code = task.eq_code task_action.eq_type_name = mq_eq_action.eq_type_name task_action.data = lua.FormatJsonString( mq_eq_action.data ) task_action.value = strActionValue nRet, strRetInfo = m3.CreateDataObj( strLuaDEID, task_action ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), '创建【任务动作】对象失败!'..strRetInfo ) end end